package com.pedro.streamer.exo;

import static android.content.Context.MODE_APPEND;
import static android.content.Context.MODE_PRIVATE;

import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.ByteBuffer;

public final class FileUtil {

    private final static String FILE_EXTENSION_SEPARATOR = ".";
    private static final int NOT_FOUND = -1;
    private static final char EXTENSION_SEPARATOR = '.';
    public static final String EXTENSION_SEPARATOR_STR = Character.toString(EXTENSION_SEPARATOR);
    private static final char UNIX_SEPARATOR = '/';
    private static final char WINDOWS_SEPARATOR = '\\';

    public static String getFileNameFromUrl(String url) {
        if (TextUtils.isEmpty(url)) {
            return "";
        }
        return url.substring(url.lastIndexOf(File.separator) + 1);
    }

    private static File makeDir(String path) {
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }

    public static File createFile(String path, String fileName) {
        if (TextUtils.isEmpty(path) || TextUtils.isEmpty(fileName)) {
            return null;
        }

        File file = new File(makeDir(path), fileName);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    public static String getFilePath(String path, String fileName) {
        if (TextUtils.isEmpty(path) || TextUtils.isEmpty(fileName)) {
            return "";
        }
        File file = new File(makeDir(path), fileName);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return file.getAbsolutePath();
    }

    public static boolean deleteFile(String path) {
        if (TextUtils.isEmpty(path)) {
            return false;
        }
        File file = new File(path);
        if (!file.exists()) {
            return true;
        }
        if (file.isFile()) {
            return file.delete();
        }
        if (!file.isDirectory()) {
            return false;
        }
        for (File f : file.listFiles()) {
            if (f.isFile()) {
                f.delete();
            } else if (f.isDirectory()) {
                deleteFile(f.getAbsolutePath());
            }
        }
        return file.delete();
    }

    public static StringBuilder readFile(File file) {
        StringBuilder fileContent = new StringBuilder("");
        if (file == null || !file.isFile()) {
            return fileContent;
        }
        BufferedReader reader = null;
        InputStreamReader is = null;
        try {
            is = new InputStreamReader(new FileInputStream(file), "UTF-8");
            reader = new BufferedReader(is);
            String line;
            while ((line = reader.readLine()) != null) {
                if (!fileContent.toString().equals("")) {
                    fileContent.append("\\n");
                }
                fileContent.append(line);
            }
            is.close();
            reader.close();
            return fileContent;
        } catch (IOException e) {
            throw new RuntimeException("IOException occurred. ", e);
        } finally {
            if (reader != null) {
                try {
                    if (is != null) {
                        is.close();
                    }
                    reader.close();
                } catch (IOException e) {
                    throw new RuntimeException("IOException occurred. ", e);
                }
            }
        }
    }

    public static long sizeOfDirectory(final File directory) {
        if (directory == null) {
            return 0;
        }
        if (!checkDirectory(directory)) {
            return 0;
        }
        return sizeOfDirectory0(directory);
    }

    private static boolean checkDirectory(final File directory) {
        return directory.exists() && directory.isDirectory();
    }

    public static long numOfDirectory(final File directory) {
        return numOfDirectory0(directory);
    }

    private static long numOfDirectory0(final File directory) {
        if (directory == null) {
            return 0L;
        }
        final File[] files = directory.listFiles();
        if (files == null) {  // null if security restricted
            return 0L;
        }
        long num = 0;
        try {
            for (final File file : files) {

                num += numOf0(file); // internal method
                if (num < 0) {
                    break;
                }
            }
        } catch (final Exception ioe) {
            // Ignore exceptions caught when asking if a File is a symlink.
        }
        return num;
    }

    private static long numOf0(File file) {
        if (file.isDirectory()) {
            return numOfDirectory0(file);
        } else {
            String extension = getExtension(file.getName());
            if (extension.equals("json") || extension.equals("jpg") || extension.equals("amr")) {
                return 1L;
            }
            return 0L;
        }
    }

    private static long sizeOfDirectory0(final File directory) {
        final File[] files = directory.listFiles();
        if (files == null) {  // null if security restricted
            return 0L;
        }
        long size = 0;
        try {
            for (final File file : files) {

                size += sizeOf0(file); // internal method
                if (size < 0) {
                    break;
                }
            }
        } catch (final Exception ioe) {
            // Ignore exceptions caught when asking if a File is a symlink.
        }
        return size;
    }

    private static long sizeOf0(File file) {
        if (file.isDirectory()) {
            return sizeOfDirectory0(file);
        } else {
            String extension = getExtension(file.getName());
            if (extension.equals("json") || extension.equals("jpg") || extension.equals("amr") || extension.equals("playback.dat")) {
                return file.length();
            }
            return 0L;
        }
    }

    private static String getExtension(final String filename) {
        if (filename == null) {
            return null;
        }
        final int index = indexOfExtension(filename);
        if (index == NOT_FOUND) {
            return "";
        } else {
            return filename.substring(index + 1);
        }
    }

    private static int indexOfExtension(final String filename) {
        if (filename == null) {
            return NOT_FOUND;
        }
        final int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
        final int lastSeparator = indexOfLastSeparator(filename);
        return lastSeparator > extensionPos ? NOT_FOUND : extensionPos;
    }

    private static int indexOfLastSeparator(final String filename) {
        if (filename == null) {
            return NOT_FOUND;
        }
        final int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
        final int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
        return Math.max(lastUnixPos, lastWindowsPos);
    }

    public static void writeString(File file, String url) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file, true);
            fos.write(url.getBytes("utf-8"));
            fos.write("\r\n".getBytes("utf-8"));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 获取文件写入文件
     * 将文件写入到项目的私有目录中
     */
    //写数据
    public static boolean writeFile(Context context, String fileName, String writestr) {
        FileOutputStream fout = null;
        try {
            fout = context.openFileOutput(fileName, MODE_PRIVATE);
            byte[] bytes = writestr.getBytes();
            fout.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (fout != null) {
                    fout.close();
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }


    }

    public static boolean writeFile(Context context, String fileName, byte[] bytes) {
        FileOutputStream fout = null;
        try {
            fout = context.openFileOutput(fileName, MODE_APPEND);
            fout.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (fout != null) {
                    fout.close();
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }

    }

    public static boolean writeFile(Context context, String fileName, ByteBuffer videodata) {
        FileOutputStream fout = null;
        try {
            fout = context.openFileOutput(fileName, MODE_PRIVATE | MODE_APPEND);
            byte[] bytes = new byte[500];
            int offset = 0;
            boolean read = true;
            int length = 500;
            int count = videodata.limit();
            while (read) {
                if (count < length) {
                    length = count;
                    read = false;
                }
                videodata.get(bytes);
                fout.write(bytes);
                count = count - length;
                offset = offset + length;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (fout != null) {
                    fout.close();
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }


    }


    //读数据
    public static String readFile(Context context, String fileName) {
        if (TextUtils.isEmpty(fileName) || context == null) {
            return null;
        }
        String res = "";
        FileInputStream fin = null;
        try {
            fin = context.openFileInput(fileName);
            int length = fin.available();
            byte[] buffer = new byte[length];
            fin.read(buffer);
            res = new String(buffer, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fin != null) {
                    fin.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return res;
    }

    public static boolean isExists(String url) {
        if (TextUtils.isEmpty(url)) {
            return false;
        }
        File file = new File(url);
        if (file.exists()) {
            return true;
        }
        return false;
    }

    public static void saveSdcard(String message) {
        try {
            message = "Opengl : " + message;
            String fileName = "bugtest"
                    + ".txt";
            String path = "";
            if (Environment.getExternalStorageState().equals(
                    Environment.MEDIA_MOUNTED)) {
                // 存在sd卡
                path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar + "tsy-android-sdk_demo";

            }
            File dir = new File(path);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            FileOutputStream fos = new FileOutputStream(path + File.separatorChar + fileName, true);
            fos.write(message.toString().getBytes());
            fos.close();
        } catch (Exception e) {
        }
    }

    public static void fileCopy(File source, File dest) throws IOException {
        InputStream input = null;
        OutputStream output = null;
        try {
            input = new FileInputStream(source);
            output = new FileOutputStream(dest);
            byte[] buf = new byte[1024];
            int bytesRead;
            while ((bytesRead = input.read(buf)) > 0) {
                output.write(buf, 0, bytesRead);
            }
        } catch (Exception e) {
        } finally {
            try {
                if (input != null) {
                    input.close();
                }
                if (output != null) {
                    output.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static boolean wiriteFile(File file, InputStream stream) {
        boolean result = false;
        if (file != null && stream != null) {
            OutputStream output = null;
            InputStream inputStream = stream;
            try {
                output = new FileOutputStream(file);
                byte[] buf = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buf)) > 0) {
                    output.write(buf, 0, bytesRead);
                }
                result = true;
            } catch (Exception e) {
                result = false;
            } finally {
                try {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (output != null) {
                        output.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }


}